extends RefCounted
class_name Buff

func on_apply(buff_state: BuffState) -> void:
	if not buff_state or not buff_state.data:
		push_error("BuffState或BuffData为空")
		return
		
	print("%s Buff 开始启用" % buff_state.data.get_buff_name())
	_apply_modifiers(buff_state.data.now_flat_modifiers, buff_state)
	
	# 特殊处理隐身buff
	if buff_state.data.get_buff_name() == "隐身":
		# 设置玩家半透明
		if buff_state.holder.has_method("get_visuals"):
			buff_state.holder.get_visuals().modulate.a = 0.5
		# 通知敌人管理器
		EventBus.push_event("player_stealth_start", [])

func on_tick(buff_state: BuffState) -> void:
	if not buff_state or not buff_state.data:
		push_error("BuffState或BuffData为空")
		return
		
	print("%s Buff 间隔启用" % buff_state.data.get_buff_name())
	_apply_modifiers(buff_state.data.tick_flat_modifiers, buff_state)
			
func on_remove(buff_state: BuffState) -> void:
	if not buff_state or not buff_state.data:
		push_error("BuffState或BuffData为空")
		return
		
	print("%s Buff 结束启用" % buff_state.data.get_buff_name())
	_remove_modifiers(buff_state.data.now_flat_modifiers, buff_state)
	
	# 特殊处理隐身buff
	if buff_state.data.get_buff_name() == "隐身":
		# 恢复玩家透明度
		if buff_state.holder.has_method("get_visuals"):
			buff_state.holder.get_visuals().modulate.a = 1.0
		# 通知敌人管理器
		EventBus.push_event("player_stealth_end", [])

## 应用修饰符
func _apply_modifiers(modifiers: Dictionary, _buff_state: BuffState) -> void:
	for key in modifiers:
		var value = modifiers[key] * _buff_state.get_stacks()
		if value is float or value is int:
			# 检查是玩家还是敌人
			if _buff_state.holder.get_groups().has("player"):
				# 玩家
				_apply_player_modifier(_buff_state.holder, key, value)
			else:
				# 敌人
				_apply_enemy_modifier(_buff_state.holder, key, value)
		else:
			push_warning("无效的修饰符值类型: %s" % typeof(value))

## 移除修饰符
func _remove_modifiers(modifiers: Dictionary, _buff_state: BuffState) -> void:
	for key in modifiers:
		var value = modifiers[key]
		if value is float or value is int:
			# 检查是玩家还是敌人
			if _buff_state.holder.get_groups().has("player"):
				# 玩家
				_apply_player_modifier(_buff_state.holder, key, -value)
			else:
				# 敌人
				_apply_enemy_modifier(_buff_state.holder, key, -value)
		else:
			push_warning("无效的修饰符值类型: %s" % typeof(value))

## 应用敌人修饰符
func _apply_enemy_modifier(enemy: Node, key: String, value: float) -> void:
	# 如果是血量相关的修饰符
	if key == "current_hp" or key == "health":
		# 检查敌人是否处于无敌状态
		if enemy.has_method("is_invincible_state") and enemy.is_invincible_state():
			# 无敌状态下跳过伤害
			return
			
		# 查找EnemyHealthComponent
		var health_component: EnemyHealthComponent = enemy.get_node_or_null("EnemyHealthComponent")
		if health_component:
			if value < 0:
				if Utils.get_player_stats_value("is_skill_critical"):
					if randf() < Utils.get_player_stats_value("critical_chance") / 100.0:
						health_component.damage(abs(value) * Utils.get_player_stats_value("critical_multiplier"), Color.ORANGE, true)
						return
					health_component.damage(abs(value))	
			else:
				health_component.health += value
		else:
			# 如果没有EnemyHealthComponent，尝试直接设置health属性
			if enemy.has_method("damage"):
				# 如果是伤害（负值），调用damage方法
				if value < 0:
					enemy.damage(abs(value), Color.ORANGE, Utils.get_player_stats_value("is_skill_critical"))
			elif "health" in enemy:
				enemy.health += value

## 应用玩家修饰符
func _apply_player_modifier(player: Node, key: String, value: float) -> void:
	# 如果是血量相关的修饰符
	if key == "current_hp" or key == "health":
		var current_hp = player.player_stats.get_float("current_hp")
		var new_hp = current_hp + value
		# 如果是燃烧buff，检查是否会死亡
		if value < 0 and new_hp <= 0:
			# 如果会死亡，不扣血
			return
		else:
			Utils.set_player_stats_value("current_hp", value)
	## 百分比恢复
	elif key == "heal_percent":
		var max_hp = player.player_stats.get_float("max_hp")
		var add_hp = max_hp * value
		Utils.set_player_stats_value("current_hp", add_hp)
	elif key == "mana_percent":
		var max_mp = player.player_stats.get_float("max_mp")
		var add_mp = max_mp * value
		Utils.set_player_stats_value("current_mp", add_mp)
	else:
		# 其他修饰符正常应用
		Utils.set_player_stats_value(key, value)

## 获取buff颜色
func get_buff_color(buff_name: String) -> Color:
	match buff_name:
		"中毒":
			return Color.GREEN
		"烧伤":
			return Color.ORANGE
		"灼烧":
			return Color.RED
		"燃烧":
			return Color.ORANGE
		"冰冻":
			return Color.CYAN
		"眩晕":
			return Color.YELLOW
		"流血":
			return Color.RED
		"电击":
			return Color.PURPLE
		"格挡":
			return Color.CYAN
		_:
			return Color.WHITE

## 获取buff描述
func get_description(buff_state: BuffState) -> String:
	if not buff_state or not buff_state.data:
		return ""
	
	var desc = buff_state.data.get_buff_name()
	if buff_state.get_stacks() > 1:
		desc += " (层数: %d)" % buff_state.get_stacks()
	
	var remaining = buff_state.get_remaining_percentage()
	if remaining < 1.0:
		desc += " (剩余: %.1f%%)" % (remaining * 100)
	
	return desc

